package handler

import (
	"context"
	"fmt"
	"gitee.com/worklz/dtm-tcc-demo/server-order/domain/dto"
	orderpb "gitee.com/worklz/dtm-tcc-demo/server-order/proto/order"
	"github.com/google/uuid"
	"sync"
	"time"
)

type OrderHandler struct {
	orderpb.UnimplementedOrderServiceServer                       // 关键：嵌入默认实现
	orders                                  map[string]*dto.Order // 订单存储
	txDatas                                 map[string]*TxData    // 事务数据记录 tx_id -> data
	mu                                      sync.RWMutex
}

var _ orderpb.OrderServiceServer = (*OrderHandler)(nil)

// 事务数据
type TxData struct {
	TxId    string // 事务id
	OrderId string // 订单id
	Status  string // 事务状态
}

func NewOrderHandler() *OrderHandler {
	return &OrderHandler{
		orders:  make(map[string]*dto.Order),
		txDatas: make(map[string]*TxData),
	}
}

// TryCreateOrder 创建订单-Try阶段
func (h *OrderHandler) TryCreateOrder(ctx context.Context, req *orderpb.TccCreateOrderRequest) (res *orderpb.TccCreateOrderResponse, err error) {
	h.mu.Lock()
	defer h.mu.Unlock()

	// 幂等性检查
	if txData, exists := h.txDatas[req.TxId]; exists {
		if txData.Status == "try" {
			// 已执行过Try，返回已有订单
			if order, exists := h.orders[txData.OrderId]; exists {
				res = &orderpb.TccCreateOrderResponse{
					Success: true,
					OrderId: order.OrderID,
				}
				return
			}
		}
		res = &orderpb.TccCreateOrderResponse{
			Success: false,
			Message: fmt.Sprintf("事务状态错误: %s", txData.Status),
		}
		return
	}

	// 创建订单（状态为待确认）
	orderID := uuid.New().String()
	order := &dto.Order{
		OrderID:   orderID,
		UserID:    req.UserId,
		ProductID: req.ProductId,
		Quantity:  req.Quantity,
		Amount:    req.Amount,
		Status:    "PENDING",
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}

	h.orders[orderID] = order
	h.txDatas[req.TxId] = &TxData{
		TxId:    req.TxId,
		OrderId: orderID,
		Status:  "try",
	}

	res = &orderpb.TccCreateOrderResponse{
		Success: true,
		OrderId: orderID,
	}
	return
}

// ConfirmCreateOrder 确认订单-Confirm阶段
func (h *OrderHandler) ConfirmCreateOrder(ctx context.Context, req *orderpb.TccCreateOrderRequest) (res *orderpb.TccCreateOrderResponse, err error) {
	h.mu.Lock()
	defer h.mu.Unlock()

	// 幂等性检查
	txData, exists := h.txDatas[req.TxId]
	if exists {
		if txData.Status == "confirm" {
			res = &orderpb.TccCreateOrderResponse{Success: true}
			return
		}
		if txData.Status != "try" {
			res = &orderpb.TccCreateOrderResponse{
				Success: false,
				Message: fmt.Sprintf("事务状态错误: %s", txData.Status),
			}
			return
		}
	} else {
		// 空回滚处理
		res = &orderpb.TccCreateOrderResponse{Success: true}
		return
	}

	// 更新订单状态为已确认
	order, exists := h.orders[txData.OrderId]
	if !exists {
		res = &orderpb.TccCreateOrderResponse{
			Success: false,
			Message: "订单不存在",
		}
		return
	}

	order.Status = "CONFIRMED"
	order.UpdatedAt = time.Now()
	h.orders[txData.OrderId] = order
	txData.Status = "confirm"
	h.txDatas[req.TxId] = txData

	res = &orderpb.TccCreateOrderResponse{Success: true}
	return
}

// CancelCreateOrder 取消订单-Cancel阶段
func (h *OrderHandler) CancelCreateOrder(ctx context.Context, req *orderpb.TccCreateOrderRequest) (res *orderpb.TccCreateOrderResponse, err error) {
	h.mu.Lock()
	defer h.mu.Unlock()

	// 幂等性检查
	txData, exists := h.txDatas[req.TxId]
	if exists {
		if txData.Status == "cancel" {
			res = &orderpb.TccCreateOrderResponse{Success: true}
			return
		}
		if txData.Status != "try" {
			res = &orderpb.TccCreateOrderResponse{
				Success: false,
				Message: fmt.Sprintf("事务状态错误: %s", txData.Status),
			}
			return
		}
	} else {
		// 空回滚处理
		res = &orderpb.TccCreateOrderResponse{Success: true}
		return
	}

	// 更新订单状态为已取消
	order, exists := h.orders[txData.OrderId]
	if !exists {
		res = &orderpb.TccCreateOrderResponse{
			Success: false,
			Message: "订单不存在",
		}
		return
	}

	order.Status = "CANCELED"
	order.UpdatedAt = time.Now()
	h.orders[txData.OrderId] = order
	txData.Status = "cancel"
	h.txDatas[req.TxId] = txData

	res = &orderpb.TccCreateOrderResponse{Success: true}
	return
}

// GetOrder 查询订单
func (h *OrderHandler) GetOrder(ctx context.Context, req *orderpb.GetOrderRequest) (res *orderpb.GetOrderResponse, err error) {
	h.mu.RLock()
	defer h.mu.RUnlock()

	order, exists := h.orders[req.OrderId]
	if !exists {
		err = fmt.Errorf("订单不存在")
		return
	}

	res = &orderpb.GetOrderResponse{
		OrderId:   order.OrderID,
		UserId:    order.UserID,
		ProductId: order.ProductID,
		Quantity:  order.Quantity,
		Amount:    order.Amount,
		Status:    order.Status,
	}
	return
}
